/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package guzik.lukasz.SnpEditor;

import SnpDbEntities.Category;
import SnpDbEntities.CodeTypes;
import SnpDbEntities.Snippet;
import SnpDbEntities.UserPermissions;
import com.Ostermiller.Syntax.HighlightedDocument;
import guzik.lukasz.SnpDataAPI.SnpDataAPI;
import guzik.lukasz.SnpLoginEngine.interfaces.LoginEventListener;
import guzik.lukasz.snpexplorer.interfaces.SelectedItemListener;
import java.util.ArrayList;
import java.util.logging.Logger;
import javax.swing.Action;
import org.openide.util.NbBundle;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;
//import org.openide.util.ImageUtilities;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.util.Lookup;

/**
 * Top component which displays something.
 */
@ConvertAsProperties(dtd = "-//guzik.lukasz.SnpEditor//SnpEditor//EN",
autostore = false)
public final class SnpEditorTopComponent extends TopComponent implements
	LoginEventListener, SelectedItemListener
{
    private static SnpEditorTopComponent instance;
    private HighlightedDocument document;
    private Snippet loadedSnippet = null;
    private boolean isPublicSnippet = false;
    /** path to the icon used by the component and its open action */
//    static final String ICON_PATH = "SET/PATH/TO/ICON/HERE";
    private static final String PREFERRED_ID = "SnpEditorTopComponent";

    public SnpEditorTopComponent()
    {
	initComponents();
	document = new HighlightedDocument();
	jCodeTextPane.setDocument(document);
	document.setHighlightStyle(HighlightedDocument.PLAIN_STYLE);
	jCodeTextPane.setEnabled(false);
	setButtonsEnabled(false);
	setName(NbBundle.getMessage(SnpEditorTopComponent.class, "CTL_SnpEditorTopComponent"));
	setToolTipText(NbBundle.getMessage(SnpEditorTopComponent.class, "HINT_SnpEditorTopComponent"));
//        setIcon(ImageUtilities.loadImage(ICON_PATH, true));

    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jCodeTextPane = new javax.swing.JTextPane();
        jSaveButton = new javax.swing.JButton();
        jDiscardButton = new javax.swing.JButton();

        jCodeTextPane.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                jCodeTextPaneKeyReleased(evt);
            }
        });
        jScrollPane1.setViewportView(jCodeTextPane);

        org.openide.awt.Mnemonics.setLocalizedText(jSaveButton, org.openide.util.NbBundle.getMessage(SnpEditorTopComponent.class, "SnpEditorTopComponent.jSaveButton.text")); // NOI18N
        jSaveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jSaveButtonActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(jDiscardButton, org.openide.util.NbBundle.getMessage(SnpEditorTopComponent.class, "SnpEditorTopComponent.jDiscardButton.text")); // NOI18N
        jDiscardButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jDiscardButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 440, Short.MAX_VALUE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jSaveButton, javax.swing.GroupLayout.DEFAULT_SIZE, 205, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jDiscardButton, javax.swing.GroupLayout.DEFAULT_SIZE, 205, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(11, 11, 11)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jSaveButton)
                    .addComponent(jDiscardButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void jCodeTextPaneKeyReleased(java.awt.event.KeyEvent evt)//GEN-FIRST:event_jCodeTextPaneKeyReleased
    {//GEN-HEADEREND:event_jCodeTextPaneKeyReleased
	setButtonsEnabled(loadedSnippet != null && !loadedSnippet.getData().equals(jCodeTextPane.getText()));
    }

    private void setButtonsEnabled(boolean enabled)
    {
	jSaveButton.setEnabled(enabled);
	jDiscardButton.setEnabled(enabled);
    }//GEN-LAST:event_jCodeTextPaneKeyReleased

    private void jSaveButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jSaveButtonActionPerformed
    {//GEN-HEADEREND:event_jSaveButtonActionPerformed
	loadedSnippet.setData(jCodeTextPane.getText());
	SnpDataAPI.getDefault().updateSnippet(loadedSnippet, true, isPublicSnippet);
	setButtonsEnabled(false);
    }//GEN-LAST:event_jSaveButtonActionPerformed

    private void jDiscardButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jDiscardButtonActionPerformed
    {//GEN-HEADEREND:event_jDiscardButtonActionPerformed
	jCodeTextPane.setText(loadedSnippet.getData());
	setButtonsEnabled(false);
    }//GEN-LAST:event_jDiscardButtonActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextPane jCodeTextPane;
    private javax.swing.JButton jDiscardButton;
    private javax.swing.JButton jSaveButton;
    private javax.swing.JScrollPane jScrollPane1;
    // End of variables declaration//GEN-END:variables

    /**
     * Gets default instance. Do not use directly: reserved for *.settings files only,
     * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
     * To obtain the singleton instance, use {@link #findInstance}.
     */
    public static synchronized SnpEditorTopComponent getDefault()
    {
	if(instance == null)
	{
	    instance = new SnpEditorTopComponent();
	}
	return instance;
    }

    /**
     * Obtain the SnpEditorTopComponent instance. Never call {@link #getDefault} directly!
     */
    public static synchronized SnpEditorTopComponent findInstance()
    {
	TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
	if(win == null)
	{
	    Logger.getLogger(SnpEditorTopComponent.class.getName()).warning(
		    "Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system.");
	    return getDefault();
	}
	if(win instanceof SnpEditorTopComponent)
	{
	    return (SnpEditorTopComponent) win;
	}
	Logger.getLogger(SnpEditorTopComponent.class.getName()).warning(
		"There seem to be multiple components with the '" + PREFERRED_ID
		+ "' ID. That is a potential source of errors and unexpected behavior.");
	return getDefault();
    }

    @Override
    public int getPersistenceType()
    {
	return TopComponent.PERSISTENCE_ALWAYS;
    }

    @Override
    public void componentOpened()
    {
	Lookup.getDefault().lookup(guzik.lukasz.SnpLoginEngine.interfaces.LoginEngineSPI.class).getLoginEngine().addLoginEventListener(instance);
	Lookup.getDefault().lookup(guzik.lukasz.snpexplorer.interfaces.SnpExplorerSPI.class).getSnpExplorer().addSelectedItemListener(instance);
    }

    @Override
    public void componentClosed()
    {
    }

    void writeProperties(java.util.Properties p)
    {
	// better to version settings since initial version as advocated at
	// http://wiki.apidesign.org/wiki/PropertyFiles
	p.setProperty("version", "1.0");
    }

    Object readProperties(java.util.Properties p)
    {
	if(instance == null)
	{
	    instance = this;
	}
	instance.readPropertiesImpl(p);
	return instance;
    }

    private void readPropertiesImpl(java.util.Properties p)
    {
	String version = p.getProperty("version");
    }

    @Override
    protected String preferredID()
    {
	return PREFERRED_ID;
    }

    @Override
    public void onLogin()
    {
	jCodeTextPane.setEnabled(true);
	jCodeTextPane.setEditable(false);
    }

    @Override
    public void onLogout()
    {
	jCodeTextPane.setText("");
	jCodeTextPane.setEnabled(false);
	loadedSnippet = null;
    }

    @Override
    public void onSelectedSnippet(Snippet selectedSnippet, boolean isPublic)
    {
	setButtonsEnabled(false);
	jCodeTextPane.setText("");
	loadedSnippet = selectedSnippet;
	isPublicSnippet = isPublic;

	if(selectedSnippet == null)
	{
	    jCodeTextPane.setEditable(false);
	    return;
	}

	UserPermissions connectedUsrPerms = SnpDataAPI.getDefault().getConnectedUser().getPermissions();
	if(!isPublic || connectedUsrPerms == UserPermissions.SUPER_ADMIN
		|| connectedUsrPerms == UserPermissions.ADMIN)
	{
	    jCodeTextPane.setEditable(true);
	} else if(connectedUsrPerms == UserPermissions.MODERATOR)
	{
	    ArrayList<Integer> moderators;
	    moderators = SnpDataAPI.getDefault().getCategoryModerators(loadedSnippet.getCategoryId());

	    if(moderators.contains(SnpDataAPI.getDefault().getConnectedUser().getId()))
	    {
		jCodeTextPane.setEditable(true);
	    } else
	    {
		jCodeTextPane.setEditable(false);
	    }
	} else
	{
	    jCodeTextPane.setEditable(false);
	}

	document.setHighlightStyle(getHighlightStyle(selectedSnippet.getCodeType()));
	jCodeTextPane.setText(selectedSnippet.getData());
	jCodeTextPane.setCaretPosition(0);
    }

    @Override
    public void onSelectedCategory(Category selectedCategory, boolean isPublic)
    {
	if(loadedSnippet != null)
	{
	    jCodeTextPane.setText("");
	    document.setHighlightStyle(HighlightedDocument.PLAIN_STYLE);




	}
	jCodeTextPane.setEditable(!isPublic);




    }

    private Object getHighlightStyle(CodeTypes codeType)
    {
	switch(codeType)
	{
	    case C:
	    case CPP:
		return HighlightedDocument.C_STYLE;




	    case HTML:
		return HighlightedDocument.HTML_KEY_STYLE;




	    case JAVA:
		return HighlightedDocument.JAVA_STYLE;




	    case JAVA_SCRIPT:
		return HighlightedDocument.JAVASCRIPT_STYLE;




	    case LATEX:
		return HighlightedDocument.LATEX_STYLE;




	    case PROPERTIES:
		return HighlightedDocument.PROPERTIES_STYLE;




	    case SQL:
		return HighlightedDocument.SQL_STYLE;





	    default:
		return HighlightedDocument.PLAIN_STYLE;




	}
    }

    @Override
    public Action[] getActions()
    {
	return null;


    }
}
